package com.aizuda.service.web;

import cn.hutool.core.util.StrUtil;
import com.aizuda.service.interceptor.MySSOSpringInterceptor;
import com.baomidou.kisso.SSOAuthorization;
import com.baomidou.kisso.web.handler.SSOHandlerInterceptor;
import com.baomidou.kisso.web.interceptor.SSOPermissionInterceptor;
import com.baomidou.kisso.web.interceptor.SSOSpringInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.Generated;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.InterceptorRegistration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author hjw
 * @description
 * @date 2025年06月25日 16:05
 */
@Configuration
@Component
public class ServiceWebMvcConfigurer implements WebMvcConfigurer {

    private String uploadPath;

    @Value("${file.storage.local.upload-path:#{null}}")
    public void setUploadPath(String uploadPath) {
        this.uploadPath = StrUtil.isBlank(uploadPath) ? System.getProperty("java.io.tmpdir") + File.separator : uploadPath;
    }

    @Generated
    private static final Logger log = LoggerFactory.getLogger(ServiceWebMvcConfigurer.class);
    private SSOAuthorization ssoAuthorization;
    private IExcludePaths excludePaths;


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/uploads/**")
                .addResourceLocations("file:"+uploadPath);
    }

    public void addInterceptors(InterceptorRegistry registry) {
        SSOSpringInterceptor ssoInterceptor = getSsoSpringInterceptor();
        InterceptorRegistration registration = registry.addInterceptor(ssoInterceptor);
        registration.addPathPatterns(new String[]{"/**"});
        SSOPermissionInterceptor permissionInterceptor = new SSOPermissionInterceptor();
        permissionInterceptor.setAuthorization(this.ssoAuthorization);
        InterceptorRegistration registrationPermission = registry.addInterceptor(permissionInterceptor);
        registrationPermission.addPathPatterns(new String[]{"/**"});
        List<String> eps = new ArrayList();
        eps.add("/v3/api-docs/**");
        if (null != this.excludePaths) {
            eps.addAll(this.excludePaths.getPaths());
        }

        registration.excludePathPatterns(eps);
        registrationPermission.excludePathPatterns(eps);
    }

    private static @NotNull SSOSpringInterceptor getSsoSpringInterceptor() {
        SSOSpringInterceptor ssoInterceptor = new MySSOSpringInterceptor();
        ssoInterceptor.setHandlerInterceptor(new SSOHandlerInterceptor() {
            public boolean preTokenIsNullAjax(HttpServletRequest request, HttpServletResponse response) {
                log.info("Token is null, redirecting to login page.");
                //返回异常json
                writeJson(response, HttpServletResponse.SC_FORBIDDEN, -1, "Token is null, redirecting to login page.");
                return false;
            }

            public boolean preTokenIsNull(HttpServletRequest request, HttpServletResponse response) {
                writeJson(response, HttpServletResponse.SC_FORBIDDEN, -1, "Token is null, redirecting to login page.");
                return false;
            }
        });
        return ssoInterceptor;
    }

    @Generated
    public ServiceWebMvcConfigurer(final SSOAuthorization ssoAuthorization, final IExcludePaths excludePaths) {
        this.ssoAuthorization = ssoAuthorization;
        this.excludePaths = excludePaths;
    }
    /**
     * 输出 JSON 响应
     *
     * @param response HttpServletResponse
     * @param status   HTTP 状态码，如 401、403、500 等
     * @param code     自定义业务码
     * @param message  提示消息
     */
    private static   void writeJson(HttpServletResponse response, int status, int code, String message) {
        response.setContentType("application/json;charset=utf-8");
        response.setStatus(status);
        try {
            String json = String.format("{\"code\": %d, \"message\": \"%s\"}", code, message);
            response.getWriter().write(json);
        } catch (IOException e) {
            throw new RuntimeException("写入 JSON 响应失败", e);
        }
    }

}
